package utils

import (
	"context"
	"math/big"

	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
)

// SignAndSendTx 签名并发送交易（普通ETH转账）
func SignAndSendTx(client *ethclient.Client, privKeyHex string, to common.Address, amount *big.Int, chainID *big.Int) (string, error) {
	// 解析私钥
	privateKey, err := crypto.HexToECDSA(privKeyHex)
	if err != nil {
		return "", err
	}

	// 获取发送者地址
	senderAddr := crypto.PubkeyToAddress(privateKey.PublicKey)

	// 获取发送者nonce
	nonce, err := client.PendingNonceAt(context.Background(), senderAddr)
	if err != nil {
		return "", err
	}

	// 估算gas价格
	gasPrice, err := client.SuggestGasPrice(context.Background())
	if err != nil {
		return "", err
	}

	// 估算gas限制
	gasLimit, err := client.EstimateGas(context.Background(), ethereum.CallMsg{
		From:  senderAddr,
		To:    &to,
		Value: amount,
	})
	if err != nil {
		return "", err
	}

	// 构造交易
	tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, nil)

	// 签名交易
	signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
	if err != nil {
		return "", err
	}

	// 发送交易
	if err := client.SendTransaction(context.Background(), signedTx); err != nil {
		return "", err
	}

	return signedTx.Hash().Hex(), nil
}

// WeiToEth 将wei转换为ETH
func WeiToEth(wei *big.Int) string {
	eth := new(big.Float).Quo(new(big.Float).SetInt(wei), big.NewFloat(1e18))
	return eth.String()
}